#include <iostream>
#include <vector>
#include <algorithm>
#include <typeinfo>
// typeid 运算符用来获取一个表达式的类型信息。需要包含<typeinfo>头文件才可以使用。
// 主要使用分为俩种场景：

//typeid的使用形式为typeid(expression)，其中expression是要获取类型信息的表达式。typeid运算符返回一个std::type_info对象，表示表达式的实际类型。

// 对于基本类型（int、float 等C++内置类型）的数据，类型信息所包含的内容比较简单，主要是指数据的类型。
// 对于类类型的数据（对象），类型信息是指对象所属的类、所包含的成员、所在的继承关系等。
// 我们可以通过name方法获取到这个类型，通过hash_code方法返回该类型唯一的哈希值（值得注意的是hash_code是在运行时获取的信息，hash_code也是C++11新加入的）。下面就通过hash_code方法判断了俩个变量的类型是否一致。

class A
{
public:
    virtual void print()
    {
        std::cout<< "class A" << std::endl;
    }
};
class B : public A
{
public:
    virtual void print()
    {
        std::cout<< "class B" << std::endl;
    }
};

int main(int argc, char *argv[])
{
    //注意事项 typeid返回的std::type_info删除了复制构造函数，若想保存std::type_info，只能获取其引用或者指针，例如
    // auto t1 = typeid(int); // 编译失败，没有复制构造函数无法编译
    auto &t2 = typeid(int); // 编译成功，t2推导为const std::type_info&
    auto t3 = &typeid(int); // 编译成功，t3推导为const std::type_info*


    //基本类型信息
    int x = 10;
    float y = 20;
    std::cout << typeid(x).name() << std::endl; //i
	std::cout << typeid(y).name() << std::endl; //f

    std::cout << typeid(x).hash_code() << std::endl;
	std::cout << typeid(y).hash_code() << std::endl;
    std::cout << typeid(int).hash_code() << std::endl;

    //复杂类型信息
    A a;
	B b;
    std::cout << typeid(a).name() << std::endl;
	std::cout << typeid(b).name() << std::endl;
    std::cout << typeid(a).hash_code() << std::endl;
	std::cout << typeid(b).hash_code() << std::endl;

    //基本类型比较
    if(typeid(x) == typeid(int)) //相等
    {
        std::cout << "typeid(x) == typeid(int)" << std::endl;
    }
    if(typeid(x) == typeid(y)) //不相等
    {
        std::cout << "typeid(x) == typeid(y)" << std::endl;
    }
    else
    {
        std::cout << "typeid(x) != typeid(y)" << std::endl;
    }

    const int xx = 10;
    int yy = 20;
    if(typeid(xx) == typeid(yy)) //相等 typeid的返回值忽略类型的cv限定符，typeid(const T)== typeid(T))
    {
        std::cout << "typeid(xx) == typeid(yy)" << std::endl;
    }
    //复杂类型
    B *bptr = new B();
    std::cout << typeid(bptr).name() << std::endl;
    std::cout << typeid(*bptr).name() << std::endl;

    if(typeid(*bptr) == typeid(B)) //相等
    {
        std::cout << "typeid(*bptr) == typeid(B)" << std::endl;
    }
    if(typeid(*bptr) == typeid(A)) //不相等
    {
        std::cout << "typeid(*bptr) == typeid(A)" << std::endl;
    }
    delete bptr;
    return 0;
}
